package com.intretech.umsin.auth.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.intretech.umsin.auth.service.AuthService;
import com.intretech.umsin.datasource.dao.KernDAO;
import com.intretech.umsin.security.satoken.model.AppletLoginUser;
import com.intretech.umsin.security.satoken.model.LoginUser;
import com.intretech.umsin.security.satoken.model.Role;
import com.intretech.umsin.security.satoken.utils.LoginHelper;
import com.intretech.umsin.system.enums.UserStatus;
import com.intretech.umsin.system.exception.SystemCenterException;
import com.intretech.umsin.system.vo.SysMenuVo;
import com.intretech.umsin.system.vo.SysRoleVo;
import com.intretech.umsin.system.vo.SysUserVo;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @version V1.0
 * @ClassName: AuthServiceImpl
 * @Description: 功能描述
 * @author: 李启联
 * @date: 2022-8-11 16:55
 * @Copyright: Copyright (c) 2022
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private KernDAO kernDAO;

    /**
     * 通过用户名查询用户信息
     *
     * @param account 用户名
     * @return 结果
     */
    @Override
    public LoginUser getUserInfo(String account) {
        String sql = "select u.*,d.name as dept_name,u.id as userId from sys_user u left join sys_dept d on u.dept_id = d.id  where u.enabled =1 and account = ?";

        SysUserVo user = null;
        try {
            user = kernDAO.queryForObject(sql, SysUserVo.class, account);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        if (ObjectUtils.isEmpty(user)) {
            throw new SystemCenterException("user {} not exists", account);
        }
        if (UserStatus.DISABLED.equals(user.getEnabled())) {
            //throw new SystemCenterException("user disabled","user.disabled",account);
            throw new SystemCenterException("user disabled", account);
        }
        return buildLoginUser(user);

    }

    /**
     * 通过手机号查询用户信息
     *
     * @param phonenumber 手机号
     * @return 结果
     */
    @Override
    public LoginUser getUserInfoByPhonenumber(String phonenumber) {
        String sql = "select u.*,d.name as dept_name  from sys_user u left join sys_dept d on u.dept_id = d.id  where u.enabled =1 and phone = ?";
        try {
            SysUserVo user = kernDAO.queryForObject(sql, SysUserVo.class, phonenumber);
            if(ObjectUtils.isEmpty(user)){
                throw new SystemCenterException("user not exists","user.not.exists",phonenumber);
            }
            if(UserStatus.DISABLED.equals(user.getEnabled())){
                throw new SystemCenterException("user disabled","user.disabled",phonenumber);
            }
            return buildLoginUser(user);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 通过openid查询用户信息
     *
     * @param openid openid
     * @return 结果
     */
    @Override
    public AppletLoginUser getUserInfoByOpenid(String openid) {
        // todo 自行实现 userService.selectUserByOpenid(openid);
        SysUserVo sysUser = new SysUserVo();
        if (ObjectUtil.isNull(sysUser)) {
            // todo 用户不存在 业务逻辑自行实现
        }
        if (UserStatus.DISABLED.getCode().equals(sysUser.getEnabled())) {
            // todo 用户已被停用 业务逻辑自行实现
        }
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        AppletLoginUser loginUser = new AppletLoginUser();
        loginUser.setUserId(sysUser.getId());
        loginUser.setUsername(sysUser.getUsername());
        loginUser.setUserType(sysUser.getUserType());
        loginUser.setOpenid(openid);
        return loginUser;
    }

    /**
     * 注册用户信息
     *
     * @param sysUserVo 用户信息
     * @return 结果
     */
    @Override
    public SysUserVo registerUserInfo(SysUserVo sysUserVo) {
        return null;
    }


    /**
     * 构建登录用户
     */
    private LoginUser buildLoginUser(SysUserVo user) {
        LoginUser loginUser = new LoginUser();
        loginUser.setUserId(user.getId());
        loginUser.setDeptId(user.getDeptId());
        loginUser.setUsername(user.getUsername());
        loginUser.setPassword(user.getPassword());
        loginUser.setUserType(user.getUserType());
        loginUser.setAccount(user.getAccount());
        loginUser.setMenuPermission(selectMenuPermsByUserId(user.getId()));
        loginUser.setRolePermission(selectRolePermissionByUserId(user.getId()));
        loginUser.setDeptName(user.getDeptName());
        List<Role> roles = BeanUtil.copyToList(selectRolesByUserId(user.getId()), Role.class);
        loginUser.setRoles(roles);
        return loginUser;
    }


    /**
     * 根据用户查询系统菜单列表
     *
     * @param userId 用户ID
     * @return 菜单列表
     */
    public List<SysMenuVo> selectMenuList(Long userId) {
        String sql = "select distinct m.* from sys_menu m\n" +
                " left join sys_role_menu rm on m.id = rm.menu_id\n" +
                " left join sys_user_role sur on rm.role_id = sur.role_id\n" +
                " left join sys_role r on r.id = sur.role_id\n" +
                " where m.status = '0' and r.status = '0' and sur.user_id = ?";
        List<SysMenuVo> sysMenus = null;
        try {
            sysMenus = kernDAO.queryForList(sql, SysMenuVo.class, userId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return sysMenus;
    }

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    public Set<String> selectMenuPermsByUserId(Long userId) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (LoginHelper.isAdmin(userId)) {
            perms.add("*:*:*");
        } else {
            List<SysMenuVo> sysMenus = selectMenuList(userId);
            for (SysMenuVo menu : sysMenus) {
                if (StringUtils.isNotEmpty(menu.getPerms())) {
                    perms.addAll(Arrays.asList(menu.getPerms().trim().split(",")));
                }
            }
        }
        return perms;
    }

    /**
     * 根据用户ID查询角色列表
     *
     * @param userId 用户ID
     * @return 角色列表
     */
    public List<SysRoleVo> selectRolesByUserId(Long userId)  {
        List<SysRoleVo> sysRoles = null;
        try {
            sysRoles = kernDAO.queryForList("select * from sys_role where id in (select role_id from sys_user_role where user_id = ?)", SysRoleVo.class, userId);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return sysRoles;
    }

    /**
     * 根据用户ID查询角色权限 (获取角色数据权限)
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    public Set<String> selectRolePermissionByUserId(Long userId) {
        Set<String> permsSet = new HashSet<String>();
        // 管理员拥有所有权限
        if (LoginHelper.isAdmin(userId)) {
            permsSet.add("admin");
        } else {
            List<SysRoleVo> perms = selectRolesByUserId(userId);
            for (SysRoleVo perm : perms) {
                if (ObjectUtil.isNotNull(perm)) {
                    permsSet.addAll(Arrays.asList(perm.getRoleKey().trim().split(",")));
                }
            }
        }
        return permsSet;
    }

}